package com.theorydance.esoperator.utils;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import net.sf.json.JSONObject;

public class MoneyCalc {

	/**
	 * 反向推导利息
	 * @param money 总贷款金额
	 * @param month 贷款总月数
	 * @param target 还款目标
	 * @return
	 */
	public static double calcRate(double money, int month, double target) {
		// 针对等额本息反向计算利率
		double r1 = 0;
		// 万10
		double r2 = 0.0300;
		double rate = (r1 + r2) / 2;
		// 误差一毛
		double error = 0.1;
		// 使用二分法进行计算
		while(true) {
			JSONObject json = JSONObject.fromObject(benxi(money, rate, month));
			double total = json.getJSONArray("计划").getJSONObject(0).getDouble("总额");
			
			if(Math.abs(total-target) < error) {
				System.out.println(json);
				break;
			}
			if(total > target) {
				r2 = rate;
				rate = (r1 + rate) / 2;
			}else {
				r1 = rate;
				rate = (r2 + rate) / 2;
			}
			System.out.println("月利率：千分之"+FSTools.calc_round(rate*1000, 2)+",年利率：百分之"+FSTools.calc_round(rate*12*100, 2)+",rate="+rate);
		}
		
		return rate;
	}
	
	/**
	 * 等额本金
	 * @param money 贷款金额
	 * @param rate 月利率
	 * @return
	 */
	public static Map<String,Object> benjin(double money, double rate, int month) {
		Map<String,Object> map = new HashMap<>();
		double benjin = money / month;
		/*
		 * interest = benjin*month*rate + benjin*(month-1)*rate + ... + benjin*1*rate;
		 * interest = benjin*rate*(month + (month-1) + ... +1);
		 * interest = benjin*rate*(month*(month+1)/2);
		 * interest = benjin*rate*month*(month+1)/2;
		 */
		double interest = Math.round(benjin*rate*month*(month+1)/2*1000)/1000.0;
		map.put("money", Math.round(money*1000)/1000.0);
		map.put("interest", Math.round(interest*1000)/1000.0);
		map.put("total", Math.round((money+interest)*1000)/1000.0);
		List<Map<String,Object>> plan = new ArrayList<>();
		for(int i=1;i<=month;i++) {
			Map<String,Object> item = new HashMap<>();
			item.put("本金", Math.round(benjin*1000)/1000.0);
			item.put("利息", Math.round((money - benjin*(i-1))*rate*1000)/1000.0);
			item.put("总额", Math.round((benjin + (money - benjin*(i-1))*rate)*1000)/1000.0);
			item.put("月份", "第"+i+"月");
			plan.add(item);
		}
		map.put("计划", plan);
		return map;
	}
	
	/**
	 * 等额本息
	 * @param money 贷款金额
	 * @param rate 月利率
	 * @return
	 */
	public static Map<String,Object> benxi(double money, double rate, int month) {
		Map<String,Object> map = new HashMap<>();
		/*
		 * M表示贷款总金额
		 * N代表贷款总月数
		 * R代表月利率
		 * M[n]代表第n个月还款的本金
		 * 
		 * 计算过程：
		 * 第1月：M1 + MR
		 * 第2月：M2 + (M-M1)R
		 * 第3月：M3 + (M-M1-M2)R
		 * 第n月：Mn + (M-M1-M2-...-M[n-1])R
		 * 第N月：MN + (M-M1-M2-...-M[N-1])R
		 * 关系1：M1 + M2 + M3 + ... + MN = M
		 * 关系2：每个月的本金+利息都是相同的 --> M[n] / M[n-1] = 1+R 为一个等比数列
		 * 等比数列：Sn = M1(1-r^n) / (1-r), 其中r = 1 + R
		 * SN = M1(1-r^N) / (1-r) = M, 所以M1 = M * (1-r) / (1-r^N)
		 * Mn = M1*r^(n-1)
		 * 第n月利息：RM - RM1*(1-r^(n-1))/(1-r)
		 */

		double totalInterest = 0;
		
		List<Map<String,Object>> plan = new ArrayList<>();
		double r = 1 + rate;
		double M1 = money * (1-r) / (1-Math.pow(r, month));
		for(int i=1;i<=month;i++) {
			Map<String,Object> item = new HashMap<>();
			double Mi = M1*Math.pow(r, i-1); // 第i月的本金
			Mi = Math.round(Mi*1000)/1000.0;
			double interest = rate*money - rate*M1*(1-Math.pow(r,i-1))/(1-r);
			interest = Math.round(interest*1000)/1000.0;
			item.put("本金", Mi);
			item.put("利息", interest);
			item.put("总额", Math.round((Mi + interest)*1000)/1000.0);
			item.put("月份", "第"+i+"月");
			totalInterest += interest;
			plan.add(item);
		}
		map.put("计划", plan);
		map.put("money", money);
		map.put("interest", totalInterest);
		map.put("total", money+totalInterest);
		return map;
	}
	
}
